|
|
Chapter 10 The Library Maker |
Introduction
Structural Requirements of Libraries
Hints for Programming Libraries
The Exported_Symbols Procedure
Error Messages of the Library Maker
You are probably already familiar with the Extension Library, which is supplied together with Omikron Basic.
It refers to a collection of procedures and functions, which have been coded in such a way as to fit them into
one single line; however, the editor will show only the beginning of this line. The actual program code of the
library remains invisible and cannot be modified either. Thus, a library represents a type of command extension
for Omikron Basic and corresponds approximately to "Include Files" in the programming language C.
Using the function 'Make Library' from the program menu, it is now possible
for users and programmers to generate such libraries on their own.
What type of procedures and functions are contained in a library, is either known because the programer has
written the library him- or herself or by consulting the manual accompanying the library.
Structural Requirements of Libraries
In order to be able to generate a library from a BASIC program, the source text has to meet certain requirements:
A library may only consist of procedures
and functions. Only commentaries and braces for folding up program sections are permitted outside of the use of
procedures and functions. In addition, the command COMPILER is permitted if followed by one of the two control
words "LIB_MAKER OFF" or "LIB_MAKER ON".
The first procedure names the library.
When calling this procedure, a copyright notice should be displayed. It is best to use the command FORM_ALERT
for this. The procedure may be indented and commentary lines or folding braces may precede it.
The source text has to contain a procedure
with the name Exported_Symbols. It is useful and practical to incorporate it immediately
as the second procedure into the source text . All procedures, functions, variables, fields, and labels, which
are to be callable from outside of the library, have to appear in it at least once.
While it might serve a purpose to be generous with the global availability when dealing with procedures and
functions, global variables and fields should be handled with caution, the fewer, the better. This is the easiest
way to prevent future "data leaks", which can lead to grave and difficult to understand errors down the
line.
It is best not to export any labels at all. If it seems really unavoidable to export a label, they need to be called
with GOTO or GOSUB, respectively.
Important: If you would like to access functions and procedures that are located outside the library from within the library, they have to appear in the procedure Exported_Symbols as well.
Procedures and/or functions may not
be nested. This means that another procedure definition may not be initiated from within an already existing procedure
definition.
Structure commands have to appear in
the correct order. Thus, first FOR and then NEXT, first REPEAT, then UNTIL, etc. This means that, for example,
it is not permitted to begin a loop with FOR, then to jump with GOTO to a NEXT, which is located ahead of the FOR.
But such extreme and confusing constructions should be avoided anyhow.
Structures have to have well-defined
starting and ending points, that is, each FOR requires a NEXT, etc. These also have to be located within the same
procedure or function, respectively. Of course, additional exits using EXIT are permitted.
IF constructions have to be clearly
organized as well. This requires, for example, that in the case of multi-line IFs, an ENDIF has to be present and
it has to be located behind the IF.
The corresponding applies to SELECT
structures, but the Library Maker does not check these, i.e., a library with a flawed SELECT structure will be
translated without an error message. However, once this library will be linked with programs, this will result
in errors, which then will be difficult to locate, especially for users of the library who do not possess the source
text.
Never use GOTO or GOSUB to jump from
one procedure to another. If the other procedure is not called at any other time, it will not be incorporated into
the compiled product. The jump command with GOTO or GOSUB, respectively, then leads into nothingness. And it is
really not considered to be good programming style either.
Everything having to do with the program
code, which is required for a procedure or a function, has to be included in said procedure or function itself.
Thus, libraries have to contain, e.g., DATA lines within the procedure, which also contains the READ command. An
alternative option is to place DATA lines into a pseudo procedure, which is seemingly called by the procedure with
the READ command using an "IF 0 THEN Pseudo_Procedure". However, this
alternative is not recommended!
No structure may start behind a one-line
IF (e.g., a loop or an additional IF structure), which extends over several lines.
The use of the command MEMORY_BLOCK
is not possible in libraries.
Hints for Programming Libraries
Avoid using GOTO and GOSUB. There is
nothing that cannot be handled with other constructions as well. There are a few cases, however, where the use
of GOTO or GOSUB might be sensible. Then labels - and not line numbers - have to be used as targets because the
entire library is after all contained in one single line.
Use global variables as little as possible.
Each global variable is a potential source for errors. The dangers are however lessened by the fact that all variables
that are not explicitly exported are library-local, that is, they can neither be queried nor modified from the
outside.
If it seems absolutely unavoidable to
export global variables, they should then be named with an expressive name. It should be obvious just by the name,
what purpose this exported variable serves. The names should also be chosen in such a way as to ensure that they
cannot accidentally be used for another purpose within a program text to which the library has been added.
The programmer should document all global
variables, procedures, and functions, which have been exported by his or her library so that users of this library
may not be surprised by odd side effects, e.g., containing an exported variable, procedure, or function in the
library that is also used in the user program - but in that case for different purposes.
Each library, which requires specific
data structures, should have an Init procedure in which all global variables are initialized
and arrays dimensioned and which sets the library into a well defined basic state as a whole.
If the data structures required by a
library occupy a certain amount of memory, then the library should also possess an Exit procedure
which, for example, frees occupied memory blocks and reduces arrays to their minimal size.
During the creation of the library,
the programmer has the opportunity to indicate a release date (if desired also the time) and a version number.
This opportunity should be utilized to clearly identify the library created by the programer. Information indicated
here will later appear in the library line behind the library name.
Before a library is generated, which
is to be used for a longer period of time or which is maybe also to be published, the function 'Clean
Sweep' should be called from the program menu in the editor. The editor subsequently will delete all no
longer needed symbols from the source text of the library, which will shorten the library. The Library Maker itself
does not check if an identifier has ever been used in the library.
The Exported_Symbols Procedure
The procedure Exported_Symbols is absolutely necessary for the creation of a library. All symbols (procedures, functions, variables, arrays, and labels as well), which do not appear in this procedure will be transformed into library-local symbols when the library is being generated, thus they can only be accessed from within the library. Consequently, a function can then, e.g., call an internal sub-function, which can never be accessed from the outside (that is, from the BASIC program or from other libraries). This ensures that in cases when several libraries are used no unintended overlapping is possible. Hence, two different libraries cannot contain two internal functions with the same name, which would lead to an error. Global variables of a library, which are not being exported are thus no longer accessible and modifiable from outside of the library. As a result, an error source is eliminated.
The exported symbols have to be listed in an syntactically correct form in the Exported_Symbols procedure. This means the following:
Variables and arrays have to be listed
in the procedure in the form of an assignement. In these cases it is of no significance whether they are located
on the left or on the right side of the equal sign. In the case of arrays, the number of variables has to be correct
as well.
Functions have to appear in an assihgnement
as well. This is possible only on the right side of the equal sign. A suitable variable has to be listed on the
left side of this equation. In cases of string functions, this is then a string variable.
Procedures are written as procedure
calls using the standard method. Of course, the number of parameters has to be here correct as well.
Labels can be included in Exported_Symbols
using a GOSUB or GOTO command.
However, even though the procedure Exported_Symbols is parsed by the Library Maker, it is not taken over into the library code and is thus not contained in the finished library. Therefore it may not be called either, which also would serve no purpose whatsoever. At the same time, this proves that the parameter types added to functions and procedures in Exported_Symbols, can be any the programmer desires to use. The only requirement is that whatever is listed on the left side of the equal sign has to correspond to what is written on the right side. Otherwise, the editor will not tokenize the line.
Exported_Symbols itself is a procedure without passing parameter. This procedure may also not call itself (almost recursive), because this procedure name is not needed outside of the library. The procedure Exported_Symbols would also never be included in the library. Thus, the compiler would never be able to translate a call from outside.
If a LOCAL command is located within the Exported_Symbols procedure, the subsequent variables are also treated as locals. Therefore these variables are library-local, even though they appear within the procedure. This can be used to arrange the procedure more clearly by declaring Void or Dummy as local variables of Exported_Symbols, employing them wherever parameters are needed.
Incidentally, all imported symbols definitely have to be incorporated into the Exported_Symbols procedure. These are procedures and functions, which are called from inside the library, but are defined in another library or in the program itself.
The Library Maker happens to search the Exported_Symbols procedure at the very
beginning of its work process by scanning the program from the beginning to its end. These symbols are founded
a bit faster if they are listed as far at the top of the source text as possible. Since the position of this procedure
has no further impact on the translation process, it should be listed as the second procedure, immediately after
the naming procedure. However, it should not be the first procedure because you surely do not want to name your
library "Exported_Symbols" ;-).
Error Messages of the Library Maker
A variety of different error messages can occur during the creation of a library. Similarly to the compiler, they appear in the active translation window. Insofar as they are not self-explanatory (e.g., UNTIL without REPEAT), they are discussed in detail below:
DEF PROC Exported_Symbols missing:
The Library Maker differentiates between two global procedures, functions, variables, and library-local procedures,
functions, variables. The advantage of this differentiation is that procedures with the same name do not interfere
with one another when they exist in different libraries, which are linked to the same BASIC program. So that the
Library Maker knows which procedures, functions, and variables are supposed to be global - and thus also may be
called by the BASIC program or other libraries, all identifiers have to be declared in an Exported_Symbols
procedure. If this procedure does not exist (or is empty), the library would become totally inaccessible from the
outside and therefore an error message is issued.
Not allowed command outside of PROC/FN:
A Library represents a collection of procedures and functions, which can be loaded to the program additionally if needed. In that case, only those parts are to be incorporated into the compiled product which are also really needed. The compiler is only able to determine which parts of a library are actually required if these are neatly and clearly separated. Therefore, a library may consist only of procedures and functions. Only commentaries and braces for folding up program sections are permitted outside of the use of procedures and functions as well as the command COMPILER if it has the control words "LIB_MAKER OFF" or "LIB_MAKER ON" as parameters (and only these).
MEMORY_BLOCK not allowed:
Memory blocks are not possible in libraries because how to locate them is not defined. Consequently, they have to be additionally loaded into the main program or placed into DATA's byte-by-byte and then transferred to a memory block with MEMORY using a library function/procedure (e.g., the Init procedure).
DEF PROC within DEF PROC:
Before a procedure/function has been concluded with END_PROC/END_FN, a new procedure/function definition has
begun using DEF PROC/FN. It is likely that the END_PROC/END_FN was simply forgotten.
Structure not closed:
This error occurs if a structure (FOR, WHILE, REPEAT ...) has been opened but has not been closed again before the end of the respective procedure.
Not enough memory reserved:
To generate the library code, the Library Maker requires memory in the application heap of the Omikron Basic editor. If this error message appears, you either have to close windows that are no longer needed or reserve more memory - by accessing the 'Memory Settings...' in the mode menu and - if needed - also by using the Finder to adjust the available memory setting in the 'Get Info' menu option in the file menu.
|
Tech-Support | Order | Start | Home: http://www.berkhan.com |
© 1997-1999 ![]() |